﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using System.Web.Script.Serialization;

namespace Nomad.ASPMVVM {
    public class BindingProperty {
        private class NullPropertiesConverter : JavaScriptConverter {
            public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
                throw new NotImplementedException();
            }

            public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) {
                var notNullProperties = new Dictionary<string, object>();
                foreach (var prop in obj.GetType().GetProperties()) {
                    var value = prop.GetValue(obj, BindingFlags.Public, null, null, null);
                    if (value != null) notNullProperties.Add(prop.Name, value);
                }
                
                return notNullProperties;
            }

            public override IEnumerable<Type> SupportedTypes {
                get { return GetType().Assembly.GetTypes(); }
            }
        }

        private static readonly IEnumerable<JavaScriptConverter> JavaScriptConverters = new JavaScriptConverter[] { new NullPropertiesConverter() };

        internal static BindingProperty[] TryParse(string value) {
            try {
                var json = new JavaScriptSerializer(); 
                return json.Deserialize<BindingProperty[]>(value);
            } catch {
                return null;
            }
        }
        internal static string Serialize(BindingProperty[] value) {
            try {
                var json = new JavaScriptSerializer();
                json.RegisterConverters(JavaScriptConverters);
                return json.Serialize(value);
            } catch {
                return null;
            }
        }

        public string Property { get; set; }
        public string Path { get; set; }        
        public string Format { get; set; }        
        public bool? NeedsBind { get; set; }        
        public bool? IsCommand { get; set; }

        public BindingProperty() {
            this.Format = null;
            this.NeedsBind = null;
            this.IsCommand = null;
        }
    }
}
